package com.example.demofdfs.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

import net.neoremind.sshxcute.core.ConnCredential;
import net.neoremind.sshxcute.core.Result;

//@Component("shellCommand")
public class ShellCommand implements Command {

	private final Logger logger = LoggerFactory.getLogger(ShellCommand.class);
	
//	@Value("${app.host}")
	private static String host = "192.168.225.133";
//	@Value("${app.username}")
	private static String username = "root";
//	@Value("${app.password}")
	private static String password = "root";
	private int port = 22;
	
	private JSch jsch = new JSch();;
	private Session session;
	private Channel channel = null;
	
	
	@Override
	public synchronized Result exec(String cmd) {
		
		if (session == null || ! session.isConnected())
			initConnection();
		Result result = new Result();
		try {
			channel = session.openChannel("exec");
			((ChannelExec) channel).setCommand(cmd);
			
			channel.setInputStream(null);
			channel.setOutputStream(System.out);
			
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ((ChannelExec) channel).setErrStream(baos);
            
			InputStream in = channel.getInputStream();

			channel.connect(36000);
			
            byte[] b = new byte[1024];
            int len;
            StringBuilder sb = new StringBuilder("");
            while (true) {
	            while (in.available() > 0) {
	            	if ((len = in.read(b, 0, 1024)) < 0)
	            		break;
	            	sb.append(new String(b, 0, len, "UTF-8"));
	            }
	            if (channel.isClosed()) {
	            	if ((result.rc = channel.getExitStatus()) != 0) {
	            		result.error_msg = new String(baos.toByteArray());
	            	} else {
	            		result.sysout = sb.toString();
	            	}
	            	break;
	            }
            }
			
		} catch (JSchException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			channel.disconnect();
		}
		
		return result;
	}

	@Override
	public synchronized void initConnection() {
		
		if (session != null && session.isConnected())
			return ;
		
		try {
			session = jsch.getSession(username, host, port);
			UserInfo ui = new ConnCredential(password);
			session.setUserInfo(ui);
			session.connect(36000);
			logger.warn(Thread.currentThread().getName() + " : 连接成功!" );
		} catch (JSchException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	public static void main(String[] args) {
		String cmd = "ls -a";
		
		Command c = new ShellCommand();
		Result r = c.exec(cmd);
		
		((ShellCommand) c).print(r);
	}
	
	public void print(Result r) {
	    System.out.println("   sysout : \n" + r.sysout);
		System.out.println("  error_msg :  \n" + r.error_msg);
	}
}
